<?php

namespace App\Http\Controllers\Api;

use App\Enum\AirportEnum;
use App\Enum\CodeEnum;
use App\Enum\DriverEnum;
use App\Enum\OrderEnum;
use App\Enum\RedisEnum;
use App\Enum\TravelEnum;
use App\Enum\UserEnterpriseEnum;
use App\Enum\VehicleConfigEnum;
use App\Events\CardPaySchedule;
use App\Events\OrderOrd;
use App\Lib\Jwt;
use App\Lib\sms\AliSms;
use App\Models\DriverModel;
use App\Models\OrderExtendModel;
use App\Models\OrderModel;
use App\Models\UserEnterpriseModel;
use App\Models\VillagerUserModel;
use App\Services\CommonService;
use App\Services\DonationService;
use App\Services\DriverService;
use App\Services\EnterpriseCommuteService;
use App\Services\QrcodeService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Exception;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class CommonController extends ApiBaseController
{
    protected $redis = null;

    public function __construct()
    {
        $this->redis = app("redis.connection");
    }
    public function getServicePhone(){
        return success(['phone'=>'4006089798','service_name'=>'立即呼叫客服中心']);
    }

    /**
     * 自用接口，获取一个user_id的token
     * @param Request $request
     * @return JsonResponse
     */
    public function generateToken(Request $request)
    {
        $userId = $request->user_id;
        if( empty($userId) ) return fail(CodeEnum::ERROR, 'user_id is needed.');
        $token = Jwt::createToken($userId);
        return success(['token'=>$token]);
    }

    /**
     * 手机短信发送
     * @param Request $request
     * @return JsonResponse|void
     * @author ninetyseven.
     * @date 2023-03-28 0:03
     */
    public function sendCode(Request $request)
    {
        try {
            $post = $request->post();

            $validator = Validator::make($post, [
                'tel' => 'required|regex:/^1[0-9]{10}$/'
            ]);
            if (!$validator->passes()) {
                // 验证失败，返回错误消息
                throw new \Exception($validator->errors());
            }
            $smsCode = randSmsCode();
            list($ok, $errMsg) = AliSms::sendSms($post['tel'], $smsCode, 'LOGIN');
            if (!$ok) {
                throw new \Exception($errMsg);
            }
            return success();
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 微信登录
     * @param Request $request
     * @author ninetyseven.
     * @date 2023-04-10 22:42
     */
    public function wxLogin(Request $request)
    {
        try {
            $post = $request->post();
            $data = (new CommonService())->wxLogin($post);
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 微信  Secret Token
     * @param Request $request
     * @return mixed
     * @author ycs 2023-08-03
     */
    public function wxSecretToken(Request $request)
    {
        try {
            $data = (new CommonService())->wxSecretToken();
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 微信  wxSecret
     * @param Request $request
     * @return mixed
     * @author ycs 2023-08-03
     */
    public function wxSecret(Request $request)
    {
        try {
            $post = $request->post();
            $data = (new CommonService())->wxSecret($post);
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 获取配置时间
     * @return JsonResponse|null
     */
    public function getConfigTime(): ?JsonResponse
    {
        try {
            $data = (new CommonService())->getConfigTime();
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }
    public function passwordReset(){

    }

    /**
     * 司机注册
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|void
     * @author ninetyseven.
     * @date 2023-03-28 1:04
     */
    public function register(Request $request)
    {
        try {
            $post = $request->post();

            $validator = Validator::make($post, [
                'phone' => 'required',
                'code' => 'required|numeric|digits:4',
                'password' => 'required|min:6|confirmed',
            ]);
            if (!$validator->passes()) {
                // 验证失败，返回错误消息
                throw new \Exception($validator->errors());
            }

            if (isset($post['is_register']) && in_array($post['is_register'], [DriverEnum::MODIFY_TYPE, DriverEnum::FORGET_TYPE])) {
                $data = DriverService::modifyPassword($post);
            } else {
                $data = DriverService::registerDriverInfo($post);
            }

            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }


    /**
     * 是否能联系司机
     * contactDriver
     * @param Request $request
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/2
     */
    public function contactDriver(Request $request): ?JsonResponse
    {
        try {
            $orderId = $request->get('order_id');
            $data = (new CommonService())->contactDriver($orderId);
            if ($data === false) {
                return fail(CodeEnum::ERROR, 'error', false);
            }

            return success(true);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }
    public function getVehicleConfigDigital(Request $request): ?JsonResponse
    {
        try {
            $data = $this->getVehicleConfigExcludeFromCache($request,[VehicleConfigEnum::VEHICLE_USE_TYPE_AIRPORT],OrderEnum::ORDER_PAY_DIGITAL);
            if ($data === false) {
                return fail(CodeEnum::SUCCESS, 'message',false);
            }

            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 获取用车类型和车型【except 接送机类型】
     * @param Request $request
     * @return JsonResponse|null
     */
    public function getVehicleConfig(Request $request): ?JsonResponse
    {
        try {
            $data = $this->getVehicleConfigExcludeFromCache($request,[VehicleConfigEnum::VEHICLE_USE_TYPE_AIRPORT]);
            if ($data === false) {
                return fail(CodeEnum::SUCCESS, 'message',false);
            }

            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }
    //
    public function vehicleAirportConfig(Request $request): ?JsonResponse
    {
        try {
            $data = $this->getVehicleConfigSpecifiedFromCache($request,[VehicleConfigEnum::VEHICLE_USE_TYPE_AIRPORT]);

            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 获取 排除一些用车类型的用车类型
     *
     * @param Request $request
     * @param $excludeUseType
     * @param $specifiedPayment
     * @return mixed
     * @throws Exception
     */
    private function getVehicleConfigExcludeFromCache(Request $request, $excludeUseType, $specifiedPayment=null)
    {
        return $this->vehicleConfigFromCache($request, $excludeUseType,[], $specifiedPayment);
    }
    /**
     * 获取 指定类型的用车类型
     *
     * @param Request $request
     * @param $specifiedUseType
     * @param $specifiedPayment
     * @return array
     * @throws Exception
     */
    private function getVehicleConfigSpecifiedFromCache(Request $request, $specifiedUseType, $specifiedPayment=null): array
    {
        $data = $this->vehicleConfigFromCache($request,[], $specifiedUseType, $specifiedPayment)[0];
        $result = [];
        Log::notice('specified data=>'.var_export($data,true));
        if( !empty($data) ) foreach( $data as $id=>$name) $result[] = ['value'=> $id, 'label'=>$name];
        return $result;
    }

    /**
     * 从缓存获取数据
     *
     * @param Request $request
     * @param array $excludeUseType
     * @param array $specifiedUseType
     * @param $specifiedPayment
     * @return mixed
     * @throws Exception
     */
    private function vehicleConfigFromCache(Request $request, array $excludeUseType=[], array $specifiedUseType=[], $specifiedPayment=null )
    {
        // 验证城市来源，转为合法数据（直辖市code降级）
        $cityCode = self::_validCitySource($request);

        // 验证支付 方式
        if (empty($request->payment) || !in_array($request->payment,array_keys(OrderEnum::ORDER_PAY_KEYS))) {   throw new \Exception('参数出错：payment');}
        $payment = OrderEnum::ORDER_PAY_KEYS[$request->payment];
        if( !empty($specifiedPayment) && $payment !== $specifiedPayment ){   throw new \Exception('支付方式出错');}

        $platformId = self::getPlatformId();

        $eut = empty($excludeUseType)?'':implode(',', $excludeUseType);
        $out = empty($specifiedUseType)?'':implode(',', $specifiedUseType);
        $redisKey = sprintf(VehicleConfigEnum::VEHICLE_CONFIG_KEY, $cityCode,$platformId, $payment,$eut,$out);

        // 构造参数
        $params = [
            'city_code'     => $cityCode,
            'platform_id'   => $platformId,
            'payment'       => $payment,
            'exclude_use_type'      => $excludeUseType,
            'specified_use_type'    => $specifiedUseType
        ];
        $ttl = VehicleConfigEnum::VEHICLE_CONFIG_TIMEOUT;
        return self::_cacheableData($redisKey, $ttl, (new CommonService()), 'getVehicleConfig', $params, $request);
    }
    /**
     * 注销用户
     * @param Request $request
     * @return JsonResponse|null
     */
    public function accountCancellation(Request $request): ?JsonResponse
    {
        try {
            $userId = $request->post('user_id');
            if (empty($userId)) {
                throw new \Exception('用户id不能为空');
            }

            $res = (new CommonService())->updateUserStatus($userId);
            if ($res !== true) {
                throw new \Exception('注销失败');
            }

            return success();
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }


    /**
     * 切换身份.
     * @param Request $request
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023-04-11 21:54
     */
    public function checkoutIdentity(Request $request): ?JsonResponse
    {
        try {
            $post = $request->post();
            $res = (new CommonService())->checkoutIdentity($post);
            if ($res !== true) {
                return fail(CodeEnum::ERROR, '切换身份失败');
            }
            return success();
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 切换身份列表.
     * @return JsonResponse|null
     */
    public function checkoutList(): ?JsonResponse
    {
        try {
            $data = (new CommonService())->checkoutList();
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 云存储上传
     * @param Request $request
     * @return array|JsonResponse|mixed|void
     */
    public function aliUpload(Request $request)
    {
        $result = [];
        $appId = self::getPlatformId();

        $validate = [
            'size' => 8 * 1024 * 1024,
            'ext' => ['jpg', 'png', 'jpeg', 'gif']
        ];

        $file = $request->file('file');
        if (is_array($file)) {
            foreach ($file as $item) {
                $ext = $item->getClientOriginalExtension();
                $size = $item->getSize();
                //验证
                if (!in_array($ext, $validate['ext'])) {
                    return fail(CodeEnum::PARAM_ERROR, '文件格式不符合');
                }
                if ($size > $validate['size']) {
                    return fail(CodeEnum::PARAM_ERROR, '文件过大');
                }
                $row = CommonService::aliUploadFile($item->getPathname(), $ext, TravelEnum::APP_PLATFORM_ID[$appId]);
                if ($row['code'] != CodeEnum::SUCCESS) {
                    return fail($row['code'], $row['msg']);
                }
                $result[] = $row['data'];
            }
        } else {
            $ext = $file->getClientOriginalExtension();
            $size = $file->getSize();
            //验证
            if (!in_array($ext, $validate['ext'])) {
                return fail(CodeEnum::PARAM_ERROR, '文件格式不符合');
            }
            if ($size > $validate['size']) {
                return fail(CodeEnum::PARAM_ERROR, '文件过大');
            }
            $row = CommonService::aliUploadFile($file->getPathname(), $ext, TravelEnum::APP_PLATFORM_ID[$appId]);
            if ($row['code'] != CodeEnum::SUCCESS) {
                return fail($row['code'], $row['msg']);
            }
            $result = $row['data'];
        }
        return success($result);
    }

    /**
     * 二维码司机生成
     * qrcodeDriverInfo
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/1
     */
    public function qrDriverCode(): ?JsonResponse
    {
        try {
            $userId = request()->userId ? request()->userId : 1;
            $driverQrcodeUrl = DriverModel::query()->where(['id'=>$userId])->value('qrcode_url');
            if( empty($driverQrcodeUrl) ){
                $url = sprintf(TravelEnum::QRCODE_INFO_URL[TravelEnum::QRCODE_TYPE_DRIVER_INFO], env('BASE_URL'), $userId);

                $driverQrcodeUrl = QrcodeService::getQrcode($url, $userId, 'qrcode');
                DriverModel::query()->where(['id'=>$userId])->update(['qrcode_url'=>$driverQrcodeUrl]);
            }

            $result = [
                'code_url' => $driverQrcodeUrl
            ];

            return success($result);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 二维码村民生成
     * qrVillagerCode
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/1
     */
    public function qrVillagerCode(): ?JsonResponse
    {
        try {
            $userId = request()->userId ? request()->userId : 1;
            $url = sprintf(TravelEnum::QRCODE_INFO_URL[TravelEnum::QRCODE_TYPE_VILLAGER_INFO], env('BASE_URL'), $userId);

            $codeUrl = QrcodeService::getQrcode($url, $userId, 'qrcode');
            $result = [
                'code_url' => $codeUrl
            ];

            return success($result);
        } catch (\Exception $e) {
            Log::error('qrVillagerCode, QrcodeService::getQrcode result='.$e->getMessage());
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 二维码志愿者生成
     * qrVillagerCode
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/1
     */
    public function qrVolunteerCode(Request $request): ?JsonResponse
    {
        try {
            $orderId = $request->get('order_id', 1);
            $url = sprintf(TravelEnum::QRCODE_INFO_URL[TravelEnum::QRCODE_TYPE_VOLUNTEER_INFO], env('BASE_URL'), $orderId);

            $codeUrl = QrcodeService::getQrcode($url, $orderId, 'qrcode');
            $result = [
                'code_url' => $codeUrl
            ];

            return success($result);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 订单二维码
     * qrVillagerCode
     * @param Request $request
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/1
     */
    public function qrOrderCode(Request $request): ?JsonResponse
    {
        try {
            $orderId = $request->get('order_id', 1);

            $url = sprintf(TravelEnum::QRCODE_INFO_URL[TravelEnum::QRCODE_TYPE_ORDER], env('BASE_URL'), $orderId, time());

            $codeUrl = OrderExtendModel::query()->where(['order_id'=>$orderId])->value('qrcode_url');
            // 动态生成
            if( empty($codeUrl) )
            {
                $s = microtime(true);
                $codeUrl = QrcodeService::getQrcode($url, $orderId, 'qrcode');
                Log::warning('qrOrderCode generate qrcode time.'.(microtime(true)-$s));
            }
            $result['code_url'] = $codeUrl;
            $result['code_in_url'] = $url;

            return success($result);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 活动二维码
     * qrActivityOrderCode
     * @param Request $request
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/14
     */
    public function qrActivityOrderCode(Request $request): ?JsonResponse
    {
        try {
            $activityId = $request->get('activity_id', 1);
            $volunteerId = $request->get('volunteer_id', 1);
            $url = sprintf(TravelEnum::QRCODE_INFO_URL[TravelEnum::QRCODE_TYPE_ACTIVITY_ORDER], env('BASE_URL'), $activityId, $volunteerId);

            $codeUrl = QrcodeService::getQrcode($url, $activityId, 'qrcode');
            $result = [
                'code_url' => $codeUrl
            ];

            return success($result);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 司机信息(二维码)
     * qrcodeDriverInfo
     * @param Request $request
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/1
     */
    public function qrcodeDriverInfo(Request $request): ?JsonResponse
    {
        try {
            $info = (new DriverService())->getDriverInfo($request->get('driver_id', 5));

            $result = [
                'type' => TravelEnum::QRCODE_TYPE_DRIVER_INFO,
                'info' => $info,
                'user_info' => $info,
            ];
            return success($result);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 村民-个人信息
     * qrcodeDriverInfo
     * @param Request $request
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/1
     */
    public function qrcodeVillagerInfo(Request $request): ?JsonResponse
    {
        try {
            $userId = $request->get('user_id', 1);
            $info = VillagerUserModel::query()->where('id', $userId)->first();

            $result = [
                'type' => TravelEnum::QRCODE_TYPE_VILLAGER_INFO,
                'user_info' => $info,
            ];
            return success($result);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 志愿者-个人信息
     * qrcodeDriverInfo
     * @param Request $request
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/1
     */
    public function qrcodeVolunteerInfo(Request $request): ?JsonResponse
    {
        try {
            $orderId = $request->get('order_id', 1);
            $orderInfo = OrderModel::query()->where('id', $orderId)->first();

            if ($orderInfo) {
                $url = sprintf(TravelEnum::QRCODE_INFO_URL[TravelEnum::QRCODE_TYPE_ORDER], env('BASE_URL'), $orderId);
                $result['code'] = CodeEnum::SUCCESS;
                $result['type'] = TravelEnum::PLATFORM_DONATION;
                $result['code_url'] = $url;
            } else {
                $result['code'] = CodeEnum::ERROR;
                $result['type'] = TravelEnum::PLATFORM_DONATION;
                $result['code_url'] = '';
            }

            return success($result);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }
    private function _authOrderId($orderId1, $orderId2)
    {
        if( $orderId1 != $orderId2 && !empty($orderId2) )
        {
            throw new \Exception('请从订单详情中操作扫码核销。');
        }
    }

    /**
     * 捐赠者的 - 订单核销
     * qrcodeOrderInfo
     * @param Request $request
     * @return JsonResponse|null
     * @date 2023/11/08
     */
    public function qrcodeOrderInfo(Request $request): ?JsonResponse
    {
        $params['order_id']     = $request->get('order_id');
        $params['user_id']      = $request->get('user_id');
        $params['app_order_id'] = $request->get('app_order_id');// 从司机端的订单详情扫码一带来的订单ID
        $params['driver_id']    = $request->get('driver_id');


        try {
            // 确保订单来源正确
            if( empty($request->admin_id) ) $this->_authOrderId($params['order_id'], $params['app_order_id']);

            DB::beginTransaction();
            $result = CommonService::codeOrderOrd($params['order_id'], $params['driver_id']);

            $adminInfo = [
                'admin_id'      => $request->admin_id,
                'admin_name'    => $request->admin_name
            ];
            // 触发订单取消成功后的事件20230821 by LC
            event(new OrderOrd($result,$adminInfo));

            DB::commit();
            return success($result);
        } catch (\Exception $e) {
            Log::error("核销订单失败:".$e->getMessage());
            DB::rollBack();
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }


    /**
     * 核销活动, 需要司机在订单详情中扫码。
     * @param Request $request
     * @return JsonResponse|null
     */
    public function qrcodeActivity(Request $request): ?JsonResponse
    {
        try {
            DB::beginTransaction();
            $orderId = $request->get('app_order_id');
//            $activityId = $request->get('activity_id');
            $driverId = $request->get('driver_id');

            if( empty($orderId) ){
                throw new \Exception("请在订单详情中扫码核销。");
            }

            $result = CommonService::codeOrderOrd($orderId, $driverId);

            // 触发订单取消成功后的事件20230821 by LC
            event(new OrderOrd($result,[]));
            DB::commit();
            return success($result);
        } catch (\Exception $e) {
            DB::rollBack();
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }


    /**
     * 账号密码/手机号登录
     * @param Request $request
     * @return JsonResponse|void
     * @throws \Exception
     * @author ninetyseven.
     * @date 2023-03-26 15:02
     */
    public function login(Request $request)
    {
        try {
            $post = $request->post();
            //区分账号登录还是手机号登录
            if (isset($post['tel'])) {
                $data = (new CommonService())->telLogin($post);
            } else {
                $data = (new CommonService())->accountLogin($post);
            }
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 我的-钱包
     * @param Request $request
     * @return JsonResponse|void
     * @author ninetyseven.
     * @date 2023-04-05 16:07
     */
    public function walletList(Request $request)
    {
        try {
            $params = [
                'user_id' => $request->userId,
                'platform_id' => self::getPlatformId(),
            ];
            $data = (new CommonService())->getWalletList($params);
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 我的-钱包
     * @param Request $request
     * @return JsonResponse|void
     * @author ninetyseven.
     * @date 2023-04-05 16:07
     */
    public function feedback(Request $request)
    {
        try {
            $params = [
                'description' => $request->description,
                'images' => $request->images
            ];
            $data = (new CommonService())->feedback($params);
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 获取城市的机场信息
     *
     * @param Request $request
     * @return JsonResponse|null
     */
    public function getAirport(Request $request): ?JsonResponse
    {
        try {
            // 验证城市来源，转为合法数据（直辖市code降级）
            $cityCode = self::_validCitySource($request);

            $redisKey = sprintf(RedisEnum::R_CITY_AIRPORT_KEY, $cityCode);

            $data = $this->_cacheableData($redisKey, RedisEnum::R_CITY_AIRPORT_TO, (new CommonService()),'getAirport', $cityCode, $request );
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 获取公益出行产品列表
     *
     * @return JsonResponse|null
     */
    public function getCardGYCX(): ?JsonResponse
    {
        try {
            if( self::getPlatformId() != TravelEnum::PLATFORM_DONATION ){
                throw new \Exception('此产品只供捐赠者使用');
            }

            $data = (new DonationService())->getCardGYCX();
//            Log::debug(var_export($data,true));
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 获取 企业通勤卡列表
     * @return JsonResponse|null
     */
    public function getCardCommute(): ?JsonResponse
    {
        try {
            if( self::getPlatformId() != TravelEnum::PLATFORM_DONATION ){
                throw new \Exception('此产品只供捐赠者使用');
            }

            $data = (new DonationService())->getCardCommute();
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }
    public function getEnterpriseInfo(Request $request): ?JsonResponse
    {
        try {
            if( self::getPlatformId() != TravelEnum::PLATFORM_DONATION ){
                throw new \Exception('此产品只供捐赠者使用');
            }
            $userId = $request->userId;

            $redisKey = sprintf(RedisEnum::R_ENTERPRISE_INFO_KEY, $userId);
            $data = $this->_cacheableData($redisKey, RedisEnum::EXPIRE_TIME_DEFAULT_DAY, (new DonationService()),'getEnterpriseInfo',$userId,$request);
//            $data = (new DonationService())->getEnterpriseInfo($request);

            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }
    public function getGycxPaymentList(Request $request): ?JsonResponse
    {
        try {
            if( self::getPlatformId() != TravelEnum::PLATFORM_DONATION ){
                throw new \Exception('此功能只供捐赠者使用');
            }

            $data = (new DonationService())->getGycxPaymentList($request);
            Log::debug(var_export($data,true));
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 获取 企业通勤明细
     * @param Request $request
     * @return JsonResponse|null
     */
    public function getCommutePaymentList(Request $request): ?JsonResponse
    {
        try {
            if( self::getPlatformId() != TravelEnum::PLATFORM_DONATION ){
                throw new \Exception('此功能只供捐赠者使用');
            }

            $data = (new DonationService())->getCommutePaymentList($request);
            Log::debug(var_export($data,true));
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 购买 公益出行卡
     * 接口POST参数：
     *      card_id:卡ID
     * @param Request $request
     * @return JsonResponse|null
     */
    public function buyCardGYCX(Request $request): ?JsonResponse
    {
        return $this->_buyCard($request);
    }
    public function buyCardCommute(Request $request): ?JsonResponse
    {
        try {
            // 1. 确保企业已经添加
            // 1.1 如果 没有企业ID，则添加企业
            if( empty($request->enterprise_id) ){
                $this->_createEnterprise($request);
            }else {
                // 1.2 企业信息合法
                $enterprise = UserEnterpriseModel::query()->find($request->enterprise_id);
                if (empty($enterprise))
                    throw new \Exception('未添加企业：而企业又不存在。');
                if ($enterprise->user_id != $request->userId)
                    throw new \Exception('未添加企业：用户信息与企业信息不匹配。');
            }

        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
        // 购买卡
        return $this->_buyCard($request);
    }
    private function _buyCard(Request $request): ?JsonResponse
    {
        try {
            // 验证手机号通过
            parent::validUserAccess($request->userId);

            DB::beginTransaction();
            if( self::getPlatformId() != TravelEnum::PLATFORM_DONATION ){
                throw new \Exception('此产品只供捐赠者使用');
            }
            $cardId = $request->input('card_id');
            if( empty($cardId) ){
                throw new \Exception('未选择产品。');
            }

            $data = (new DonationService())->buyCard($request->userId, $cardId);
            // 将购买写入redis 队列处理 by LC
            event(new CardPaySchedule($data));
            DB::commit();
            return success($data);
        } catch (\Exception $e) {
            DB::rollBack();
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * SDK活体检测结果查询
     * @param Request $request
     * @return JsonResponse
     */
    public function getFaceVerify(Request $request): JsonResponse
    {
        try {
            $data = (new CommonService())->getFaceVerify($request->all());
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 人脸身份证比对
     * @param Request $request
     * @return JsonResponse
     */
    public function faceIdCardCompare(Request $request): JsonResponse
    {
        try {
            $data = (new CommonService())->faceIdCardCompare($request->all());
            return success($data);
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 活动订单核销 :: 此接口作废
     * qrcodeActivityOrderInfo
     * @param Request $request
     * @return JsonResponse|null
     * @author ninetyseven.
     * @date 2023/5/14
     */
    public function qrcodeActivityOrderInfo(Request $request): ?JsonResponse
    {
        try {
            throw new \Exception('此接口作废');
        } catch (\Exception $e) {
            return fail(CodeEnum::ERROR, $e->getMessage());
        }
    }

    /**
     * 添加 企业
     * @param Request $request
     * @return void
     * @throws \Exception
     */
    private function _createEnterprise(Request $request)
    {
        try {
            // 验证企业名称是否存在
            self::_validEnterpriseName($request->enterprise_name);
            // 验证手机号在企业通勤服务中是否存在
            EnterpriseCommuteService::validMobileExists($request->contactor_phone);


            $data = [
                'enterprise_name' => $request->enterprise_name,
                'contactor' => $request->contactor,
                'phone' => $request->contactor_phone,
                'email' => $request->email,
                'status' => UserEnterpriseEnum::STATUS_ACCOUNT_APPLY,
                'user_id' => $request->userId
            ];
            $res = UserEnterpriseModel::query()->create($data);
            if (empty($res)) {
                throw new \Exception('写入企业失败。');
            }
        }catch (\Exception $e){
            Log::error("添加企业失败：".$e->getMessage());
            throw new \Exception('添加企业失败。');
        }
    }
    private static function _validEnterpriseName($name)
    {
        $exists = UserEnterpriseModel::query()->where(['enterprise_name'=>$name])->exists();
        if( $exists ){
            throw new \Exception('添加企业失败：此企业名称已经存在。');
        }
    }

}
